﻿using System;
using System.Collections.Generic;
using System.Composition;
using System.Linq;


namespace GaleSong
{
    /// <summary>
    ///     Concrete <see cref="IPadManager{T}" /> with manages <see cref="IPad" /> items,
    ///     it uses MEF to construct the <see cref="IPad" />s.
    /// </summary>
    public class PadManager<T> : BindableBase, IPadManager<T> where T : IPad
    {
        #region Constructor

        #endregion

        #region Property

        [ImportMany]
        protected T[] InternalItems { get; set; }

        #endregion

        #region Method

        protected virtual void ConfigParts()
        {
            if(InternalItems == null || InternalItems.Length == 0)
            {
                return;
            }

            items.Clear();
            items.AddRange(InternalItems);
        }

        #endregion

        #region IPadManager Members

        private readonly IObservableCollection<T> items = new BindableCollection<T>();

        public IObservableCollection<T> Items
        {
            get { return items; }
        }

        public T this[string name]
        {
            get { return items.FirstOrDefault(item => string.Equals(item.Name, name)); }
        }

        #endregion

        #region IPadImportsSatisfiedNotification Members

        [OnImportsSatisfied]

        public void OnImportsSatisfied()
        {
            ConfigParts();
        }

        #endregion
    }

    /// <summary>
    ///     Extends the <see cref="IPadManager{T}" /> that support <see cref="IPadMetaData" />.
    /// </summary>
    /// <typeparam name="T">IPad</typeparam>
    /// <typeparam name="TMetadata">The type of the metadata.</typeparam>
    public class PadManager<T, TMetadata> : BindableBase, IPadManager<T>
        where T : IPad
        where TMetadata : IPadMetaData
    {
        #region Property

        [ImportMany]
        protected ExportFactory<T, TMetadata>[] InternalItems { get; set; }

        #endregion

        #region Method

        protected virtual void ConfigPads()
        {
            if(InternalItems == null || InternalItems.Length == 0)
            {
                return;
            }

            _items.Clear();

            //Sort items according to metadata's Index
            SortItems();
        }

        protected virtual void SortItems()
        {
            IEnumerable<T> items = InternalItems.OrderBy(it => it.Metadata.PadName).Select(it => it.CreateExport().Value);

            Items.AddRange(items);
        }

        #endregion

        #region IPadManager Members

        private readonly IObservableCollection<T> _items = new BindableCollection<T>();

        public IObservableCollection<T> Items
        {
            get { return _items; }
        }

        public T this[string name]
        {
            get { return _items.FirstOrDefault(item => string.Equals(item.Name, name)); }
        }

        #endregion

        #region IPartImportsSatisfiedNotification Members

        [OnImportsSatisfied]

        public void OnImportsSatisfied()
        {
            ConfigPads();
        }

        #endregion
    }
}